package com.hkpw.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import com.hkpw.common.core.domain.R;
import com.hkpw.system.config.HkConfig;
import com.hkpw.system.constants.HkCollegeSafeApi;
import com.hkpw.system.domain.DoorEventNotify;
import com.hkpw.system.domain.vo.DoorEventDataVo;
import com.hkpw.system.domain.vo.DoorEventResult;
import com.hkpw.system.domain.vo.EventSubscribeViewVo;
import com.hkpw.system.domain.vo.EventsSubscribeViewResultVo;
import com.hkpw.system.mapper.DoorEventNotifyMapper;
import com.hkpw.system.service.IDoorEventNotifyService;
import com.hkpw.system.utils.HkFaceApiUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 门禁异步通知Service业务层处理
 *
 * @author Andy
 * @date 2022-09-28
 */
@Slf4j
@Service
public class DoorEventNotifyServiceImpl implements IDoorEventNotifyService {
    @Autowired
    private HkConfig hkConfig;


    @Autowired
    private DoorEventNotifyMapper doorEventNotifyMapper;

    @Override
    public int dealDoorEventNotify(DoorEventResult doorEventResult) {
        AtomicInteger count = new AtomicInteger();
        if (ObjectUtil.isNotNull(doorEventResult) && CollUtil.isNotEmpty(doorEventResult.getParams().getEvents())) {
            List<DoorEventResult.DoorEventResultParams.DoorEventResultEvent> eventResultEvents = doorEventResult.getParams().getEvents();

            eventResultEvents.forEach(doorEventResultEvent -> {
                log.info("event={}", doorEventResultEvent);
                DoorEventNotify doorEventNotify = new DoorEventNotify();
                doorEventNotify.setSendTime(DateUtil.parse(doorEventResult.getParams().getSendTime()));
                doorEventNotify.setEventId(doorEventResultEvent.getEventId());
                doorEventNotify.setAbility(doorEventResult.getParams().getAbility());
                doorEventNotify.setEventType(doorEventResultEvent.getEventType());

                doorEventNotify.setHappenTime(DateUtil.parse(doorEventResultEvent.getHappenTime()));
                doorEventNotify.setSrcIndex(doorEventResultEvent.getSrcIndex());
                doorEventNotify.setSrcName(doorEventResultEvent.getSrcName());
                doorEventNotify.setSrcParentIndex(doorEventResultEvent.getSrcParentIndex());
                doorEventNotify.setStatus(doorEventResultEvent.getStatus());
                doorEventNotify.setSrcType(doorEventResultEvent.getSrcType());
                doorEventNotify.setTimeout(doorEventResultEvent.getTimeout());
                JSONObject dataJson = doorEventResultEvent.getData();
                try {
                    DoorEventDataVo dataVo = JSON.parseObject(dataJson.toJSONString(), DoorEventDataVo.class);
                    doorEventNotify.setExtEventPersonNo(dataVo.getExtEventPersonNo());
                    doorEventNotify.setUserType(dataVo.getUserType());
                    doorEventNotify.setExtEventCardNo(dataVo.getExtEventCardNo());
                    doorEventNotify.setExtEventInOut(dataVo.getExtEventInOut());
                    doorEventNotify.setExtAccessChannel(dataVo.getExtAccessChannel());
                    doorEventNotify.setSvrIndexCode(dataVo.getSvrIndexCode());
                    doorEventNotify.setExtEventPictureUrl(dataVo.getExtEventPictureURL());
                    //体温信息，如果没有人员出入可能为空
                    if (ObjectUtil.isNotNull(dataVo.getExtTemp())) {
                        doorEventNotify.setTemp(dataVo.getExtTemp().getTemp());
                        doorEventNotify.setIsabnormal(dataVo.getExtTemp().getIsabnormal());
                    }
                } catch (Exception e) {
                    log.info(dataJson.toString());
                    log.error("解析异常", e);
                }
                count.addAndGet(doorEventNotifyMapper.insertDoorEventNotify(doorEventNotify));
                log.info("[记录门禁回调信息]doorEventNotify={}", doorEventNotify);
            });
        }
        return count.get();
    }

    @SneakyThrows
    @Override
    public List<EventSubscribeViewVo> getDoorEventSubscribeViewVo() {
        Map<String, String> path = HkFaceApiUtils.getHkUrlPath(HkCollegeSafeApi.DOOR_EVENT_SUBSCRIBE_VIEW_URL);
        ArtemisConfig artemisConfig = new ArtemisConfig(hkConfig.getHost(), hkConfig.getAppKey(), hkConfig.getAppSecret());
        String result = ArtemisHttpUtil.doPostStringArtemis(artemisConfig, path, null, null, null, "application/json");
        log.info("DoorEventNotifyServiceImpl.getDoorEventSubscribeViewVo():result={}", result);
        R<JSONObject> r = JSONObject.parseObject(result, R.class);
        if (ObjectUtil.isNotNull(r) && r.getCode() == 0) {
            List<EventSubscribeViewVo> eventSubscribeViewVoList = new ArrayList<>();
            JSONObject data = r.getData();
            JSONArray detail = data.getJSONArray("detail");
            List<EventsSubscribeViewResultVo> resultVos = detail.toJavaList(EventsSubscribeViewResultVo.class);
            resultVos.forEach(eventsSubscribeViewResultVo -> {
                List<Long> eventTypes = eventsSubscribeViewResultVo.getEventTypes();
                eventTypes.forEach(event -> {
                    EventSubscribeViewVo eventSubscribeViewVo = new EventSubscribeViewVo();
                    eventSubscribeViewVo.setEventType(event);
                    eventSubscribeViewVo.setEventDest(eventsSubscribeViewResultVo.getEventDest());
                    eventSubscribeViewVoList.add(eventSubscribeViewVo);
                });

            });
            return eventSubscribeViewVoList;

        } else {
            throw new RuntimeException(r.getMsg());
        }

    }

    /**
     * 查询门禁异步通知
     *
     * @param id 门禁异步通知主键
     * @return 门禁异步通知
     */
    @Override
    public DoorEventNotify selectDoorEventNotifyById(Long id) {
        return doorEventNotifyMapper.selectDoorEventNotifyById(id);
    }

    /**
     * 查询门禁异步通知列表
     *
     * @param doorEventNotify 门禁异步通知
     * @return 门禁异步通知
     */
    @Override
    public List<DoorEventNotify> selectDoorEventNotifyList(DoorEventNotify doorEventNotify) {
        return doorEventNotifyMapper.selectDoorEventNotifyList(doorEventNotify);
    }

    /**
     * 新增门禁异步通知
     *
     * @param doorEventNotify 门禁异步通知
     * @return 结果
     */
    @Override
    public int insertDoorEventNotify(DoorEventNotify doorEventNotify) {
        return doorEventNotifyMapper.insertDoorEventNotify(doorEventNotify);
    }

    /**
     * 修改门禁异步通知
     *
     * @param doorEventNotify 门禁异步通知
     * @return 结果
     */
    @Override
    public int updateDoorEventNotify(DoorEventNotify doorEventNotify) {
        return doorEventNotifyMapper.updateDoorEventNotify(doorEventNotify);
    }

    /**
     * 批量删除门禁异步通知
     *
     * @param ids 需要删除的门禁异步通知主键
     * @return 结果
     */
    @Override
    public int deleteDoorEventNotifyByIds(Long[] ids) {
        return doorEventNotifyMapper.deleteDoorEventNotifyByIds(ids);
    }

    /**
     * 删除门禁异步通知信息
     *
     * @param id 门禁异步通知主键
     * @return 结果
     */
    @Override
    public int deleteDoorEventNotifyById(Long id) {
        return doorEventNotifyMapper.deleteDoorEventNotifyById(id);
    }

    /**
     * 清除指定天数之前的历史数据
     *
     * @param days
     * @return
     */
    @Override
    public int deleteDoorEventNotifyBeforeDays(int days) {
        //避免操作失误导致的清空数据，至少保留1天数据
        if (days <= 0) {
            days = 1;
        }
        return doorEventNotifyMapper.deleteDoorEventNotifyBeforeDays(days);
    }

    @Override
    public int cleanUselessDoorEventNotify(int days) {
        return doorEventNotifyMapper.cleanUselessDoorEventNotify(days);
    }
}
